/*
 * This file is part of b.AMP.
 *
 * b.AMP is free software: you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * b.AMP is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with b.AMP.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <bamp/rc.h>

#include <cstddef>
#include <string>

#include "data_input_test.hpp"


BAMP_DATA_INPUT_DECLARE(DataInputTest, "test");
BAMP_CLASS_LIST(bamp::DataInputPtr::cname);

const static size_t      TEST_FILE_SIZE       = 100;
const static std::string TEST_PROTOCOL_PREFIX = "test://";

static std::string readUrl(const std::string& url)
{
    // Make sure the protocol requested is supported    
    const size_t len = TEST_PROTOCOL_PREFIX.size();
    {
        const std::string prefix = url.substr(0, len);
        BAMP_ASSERT_THROW(prefix == TEST_PROTOCOL_PREFIX, NOT_IMPLEMENTED);
    }

    // Return only the useful part of the URL
    return url.substr(len);
}


DataInputTest::DataInputTest()
{
    // The plugin constructor is used to initialize the internal state
    // of a single plugin instance.
}

DataInputTest::~DataInputTest()
{
    // Nothing here.
}

void DataInputTest::open(const std::string& url)
{
    // This function opens a m_ It must be called before all other
    // file-related functions. It closes any currently open m_
    m_pos    = 0;
    m_size   = TEST_FILE_SIZE;
    m_name   = readUrl(url);
    m_type   = "application/x-bamp-test";
    m_isOpen = true;
}

void DataInputTest::close()
{
    // As with dirClose(), a real plugin would typically release
    // resources here.
    m_isOpen = false;
}

std::string DataInputTest::getType() const
{
    // This function returns the MIME media type of the file currently
    // being read.
    BAMP_ASSERT_THROW(m_isOpen, NOT_READY);
    return m_type;
}

void DataInputTest::setHost(bamp::HostPtr host)
{
    // This is function is how b.AMP gives a way to communicate with
    // it. The host object can be used to send messages to any part of
    // the system.
    m_host = host;
}

void DataInputTest::send(bamp::MessagePtr msg)
{
    // We get here when somebody, somewhere, has sent us a message.
}

size_t DataInputTest::getPosition() const
{
    // This function returns the position of the file read cursor.
    BAMP_ASSERT_THROW(m_isOpen, NOT_READY);
    return m_pos;
}

void DataInputTest::setPosition(size_t position)
{
    // This function sets the position of the file read cursor.
    BAMP_ASSERT_THROW(m_isOpen, NOT_READY);
    BAMP_ASSERT_THROW(position < m_size, INDEX_OUT_OF_RANGE);
    m_pos = position;
}

bool DataInputTest::getSeekable() const
{
    // Input plugins do not have to support getPosition() and
    // setPosition(). This function is a way to find out.
    return true;
}

bamp::Status DataInputTest::read(char* dst, size_t& size)
{
    // If the input plugin had only one function, it would be this
    // one. The caller provides the "dst" buffer, and guarantees that
    // it is at least big enough to hold "size" bytes. We are free to
    // write less but then we have to write the actual size written
    // back to "size".
    BAMP_ASSERT_THROW(m_isOpen, NOT_READY);
    
    size = 0;

    return BAMP_READ_EOS;
}
